﻿using Domain.Entities;
using FrameworkCore.DI;
using FrameworkCore.Helpers;
using FrameworkCore.Interfaces;
using FrameworkCore.Repositories;
using Microsoft.EntityFrameworkCore;

namespace Application.Features.Groups.Repositories;

public class GroupServices : IScopedDependency
{
    private readonly ICurrentUserService _currentUserService;
    private readonly IRepository<Group> _groupRepository;
    public GroupServices(
        ICurrentUserService currentUserService,
        IRepository<Group> groupRepository)
    {
        _currentUserService = currentUserService;
        _groupRepository = groupRepository;
    }

    /// <summary>
    /// 如果指定的组不存在，则创建它；如果已存在，则返回现有组的 ID。
    /// </summary>
    /// <param name="input">要创建或检查的组信息。</param>
    /// <returns>现有组的 ID 或新创建组的 ID。</returns>
    public async Task<long> EnsureGroupExistsAsync(Group input)
    {
        // 查询是否已存在具有相同名称和代码的组
        var existingGroup = await _groupRepository.Query(x => x.Groupname == input.Groupname && x.Code == input.Code).FirstOrDefaultAsync();

        // 如果组不存在，则插入新组并返回其 ID
        if (existingGroup == null)
        {
            await _groupRepository.InsertAsync(input);
            return input.Id;
        }

        // 如果组已存在，则返回现有组的 ID
        return existingGroup.Id;
    }

    /// <summary>
    /// 查询组是否存在
    /// </summary>
    /// <param name="groupId">唯一标识</param>
    /// <param name="groupname">组名</param>
    /// <param name="groupCode">组编码</param>
    /// <returns></returns>
    public async Task<bool> ExistsAsync(long groupId, string groupname, string groupCode)
    {
        return await _groupRepository.Query(x => x.Id == groupId && x.Groupname == groupname && x.Code == groupCode).AnyAsync();
    }

    /// <summary>
    /// 查询组
    /// </summary>
    /// <param name="groupId">唯一标识</param>
    /// <param name="groupname">组名</param>
    /// <param name="groupCode">组编码</param>
    /// <returns></returns>
    public async Task<Group?> GetAsync(long groupId, string groupname, string groupCode)
    {
        var group = await _groupRepository.Query(x => x.Id == groupId).FirstOrDefaultAsync();
        if (group == null)
        {
            return null;
        }

        // 查找父组是否匹配
        bool isValidParent = await _groupRepository.Query(x => x.Id == group.ParentId && x.Groupname == groupname && x.Code == groupCode).AnyAsync();
        return isValidParent ? group : null;
    }


    /// <summary>
    /// 创建组
    /// </summary>
    /// <param name="input">输入模型</param>
    /// <returns></returns>
    public async Task CreateAsync(Group input)
    {
        var codeToExist = await _groupRepository.Query(x => x.Code == input.Code).AnyAsync();
        ExceptionHelper.ThrowIfTrue(codeToExist, $"编码已经存在");

        var groups = await _groupRepository.Query(x => x.Groupname == input.Groupname).FirstOrDefaultAsync();
        if (groups != null)
        {
            ExceptionHelper.ThrowIfTrue(groups.ParentId == input.ParentId, $"名称重复");
        }

        await _groupRepository.InsertAsync(input);
    }

    /// <summary>
    /// 修改组
    /// </summary>
    /// <param name="input">输入模型</param>
    /// <returns></returns>
    public async Task UpdateAsync(Group input)
    {
        if (input.ParentId.HasValue)
        {
            var parenIdToExist = await _groupRepository.Query(x => x.Id == input.ParentId).AnyAsync();
            ExceptionHelper.ThrowIfFalse(parenIdToExist, $"父级节点不存在");
        }

        var groupToExist = await _groupRepository.Query(x => x.Id == input.ParentId).AnyAsync();
        ExceptionHelper.ThrowIfFalse(groupToExist, "数据不存在");

        var groupNameToExist = await _groupRepository.Query(x => x.Groupname == input.Groupname && x.Id != input.Id).AnyAsync();
        ExceptionHelper.ThrowIfTrue(groupNameToExist, "名称重复");

        var codeToExist = await _groupRepository.Query(x => x.Code == input.Code && x.Id != input.Id).AnyAsync();
        ExceptionHelper.ThrowIfTrue(codeToExist, "编码重复");

        await _groupRepository.UpdateAsync(x => x
        .SetProperty(p => p.Groupname, input.Groupname)
        .SetProperty(p => p.Code, input.Code)
        .SetProperty(p => p.IsVillain, input.IsVillain)
        .SetProperty(p => p.ParentId, input.ParentId)
        .SetProperty(p => p.Remark, input.Remark)
        .SetProperty(p => p.Sort, input.Sort)
        .SetProperty(p => p.IsEnabled, input.IsEnabled),
        w => w.Id == input.Id);
    }

    /// <summary>
    /// 删除组
    /// </summary>
    /// <param name="ids">唯一标识，多个使用英文状态下的逗号（,）隔开</param>
    /// <returns></returns>
    public async Task DeleteAsync(string ids)
    {
        ExceptionHelper.ThrowIfNull(ids, "删除的唯一标识不能为空");

        List<long> idsToDelste = ids
            .Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)  // 分割字符串
            .Select(id =>
            {
                if (long.TryParse(id.Trim(), out long result))
                {
                    return result;
                }
                else
                {
                    ExceptionHelper.ThrowIfTrue(true, "无效的标识");
                    return 0;
                }
            }).ToList();

        await _groupRepository.DeleteAsync(x => idsToDelste.Contains(x.Id));
    }
}
